Warung Bebas

Senin, 07 Oktober 2013

The Client <--> Server division


The Minecraft code can be divided into two �sides� � Client and Server.
  • The Server side is responsible for maintaining the master copy of the world - updating the blocks and entities based on packets received from the client, and sending updated information to all the clients.
  • The Client side is primarily responsible for reading input from the player and for rendering the screen.
There is one server, and a number of clients which connect to it. Even in single player mode, the server and client code are running simultaneously (in separate threads).

Some parts of the code are used by both Client and Server code, for example Block methods.  If you are writing code which might be called by either Client or Server, how can you tell which side has called the code?
First preference: if your method has been passed a World object, or the Class you are extending has a World field (typically called worldObj):
  • if World.isRemote is true, this is Client side
  • if World.isRemote is false, this is Server side.
If your code has been passed a NetHandler:
  • NetHandler.isServerHandler() returns true if Server side.
As a last resort:
  • FMLcommonHandler.instance().getEffectiveSide() returns Side.SERVER or Side.CLIENT.

Client and Server run in parallel

Communication between the Client and Server sides takes place through Packets, which are sent back and forth using NetClientHandler and NetServerHandler.  The basic steps are shown in the diagram below.  There are a large number of different packets used:
* Packets from Server to Client

Some guidelines on the Client<-->Server communication here.



Communication from Client to Server

Communication from Server to Client

If you need to send packets in your mod code, Forge has thoughtfully provided PacketDispatcher to send packets to the client or the server without having to retrieve a NetServerHandler or NetClientHandler.
          .sendPacketToServer()
          .sendPacketToPlayer()
          .sendPacketToAllAround()
          .sendPacketToAllInDimension()
          .sendPacketToAllPlayers()

If the existing packets don�t meet your needs, you can create a custom packet Packet250CustomPayload.  More details here.

In many cases, you won�t need to create custom packets to keep your client and server code synchronised.  The vanilla code and Forge code do this in a number of ways already:
  • Creation, Removal, Movement, health, actions etc for Entities.  This is accomplished for new Entities by Forge packet EntitySpawnPacket.  You can define a custom handler for this using EntityRegistration.setCustomSpawning().
  • Removal or placement of Blocks
  • Adding DataWatcher variables to your Entity (see here)
  • Containers (Inventory, furnace, etc)

Server Packets: Changes to Entities

The following Packets are used to inform the client about changes to Entities.  These are usually generated by
  • EntityTrackerEntry (keeps track of entities near to each player)
  • EntityPlayerMP (keeps track of player status, position, health, inventory, etc
    The Client generally handles these packets by calling methods in
    • EntityClientPlayerMP(for changes to the user / controlling player)
    • WorldClient (addition or removal of Entities)
    • Entity (for status changes to entities in general, eg health, position, etc)


    Typical server origin
    NetClientHandler (Client processing)
    Called by Client during processing
    Packet5PlayerInventory
    Change the equipped item or armour of an entity (player, other players, mob)
    EntityLivingBase.onUpdate()
    EntityTrackerEntry
    .handlePlayerInventory()

    Entity.setCurrentItemOrArmor()
    Packet6SpawnPosition
    Tells the client where the player will respawn next.
    ServerConfigurationManager
    .handleSpawnPosition()

    EntityClientPlayerMP.setSpawnChunk()
    WorldInfo.setSpawnPosition()
    Packet8UpdateHealth
    Sends updated health and food status to the client.
    EntityPlayerMP.onUpdateEntity()
    .handleUpdateHealth()

    EntityClientPlayerMP
    Packet9Respawn
    Tell the client to respawn the player at the given location.
    ServerConfigurationManager
    .transferPlayerToDimension()
    .respawnPlayer()

    .handleRespawn()
    Change dimension, create new WorldClient, change game type
    Minecraft.setDimensionAndSpawnPlayer
    PlayerControllerMP.setGameType
    Packet10Flying,
    Packet11PlayerPosition,
    Packet12PlayerLook,
    Packet13PlayerLookMove


    NetServerHandler
    .setPlayerLocation()

    Only Packet13 is ever sent from server to client.  It is sent once per second, to keep client and server synchronised.  Used as a signal to the client that the world reload after respawning has completed.
    .handleFlying()
    Update position and/or look to the new values.  Then send the same Packet with updated values (in particular the foot and eye y-values) back to the server.  Get rid of respawn screen.
    EntityClientPlayerMP
    .setPositionAndRotation()
    Packet16BlockItemSwitch
    Changes the selected hotbar slot (0..8)
    ServerConfigurationManager
    handleBlockItemSwitch()
    Change inventory.currentitem to the nominated slot.

    Packet17Sleep
    Put a player to sleep
    EntityPlayerMP.sleepInBedAt
    handleSleep()
    Put a player to sleep at the specified location, if possible.
    Entityplayer.sleepInBedAt
    Packet18Animation
    Entity performs an action
    1 = swing item
    2 = gets hurt (not used)
    3 = wake up
    6 = critical hit
    7 = magic critical hit
    EntityPlayerMP
    EntityLivingBase
    handleAnimation()
    Starts the appropriate animation (entity) or EffectRenderer
    EffectRenderer.addEffect()
    Entity
    EntityLivingBase
    EntityPlayer
    <![if !supportLineBreakNewLine]>
    <![endif]>
    Packet20NamedEntitySpawn
    Spawn an Other Player on the client
    EntityTrackerEntry
    handleNamedEntitySpawn()
    Spawn the other player on the client, set its position, look, current item, and other metadata (Datawatcher objects)
    EntityOtherPlayerMP
    WorldClient.addEntityToWorld()
    Packet22Collect
    Collect an item from the ground
    EntityLivingBase
    .onItemPickup()

    handleCollect()
    Removes the EntityItem, plays a sound effect, renders the pickup effect.  Does not actually give an item to the entity.
    WorldClient()
    EffectRenderer()
    Packet23VehicleSpawn
    Spawns a non-living Entity (boat, fireball, firework, etc)
    EntityTrackerEntry
    .getPacketForThisEntity()
    FMLNetworkHandler
    .getEntitySpawningPacket()
    handleVehicleSpawn()
    Create the Entity, set position, pitch & yaw.  If thrown, set velocity.
    WorldClient.addEntityToWorld()
    Packet24MobSpawn
    Spawn a mob
    EntityTrackerEntry
    .getPacketForThisEntity()
    FMLNetworkHandler.
    getEntitySpawningPacket()
    handleMobSpawn()
    Create the Entity, set position, pitch & yaws, and other metadata (Datawatcher objects).
    WorldClient.addEntityToWorld()
    Packet25EntityPainting
    EntityTrackerEntry
    .getPacketForThisEntity()
    handleEntityPainting()
    Create a painting
    WorldClient.addEntityToWorld()
    Packet26EntityXPOrb
    EntityTrackerEntry
    .getPacketForThisEntity()
    handleEntityExpOrb()
    Create an XP orb.
    WorldClient.addEntityToWorld()
    Packet28EntityVelocity
    EntityTrackerEntry
    .sendLocationToAllClients()
    handleEntityVelocity()
    Change the Entity�s velocity
    Entity.setVelocity()
    Packet29DestroyEntity
    Remove one or more entities from client world, i.e. client doesn�t need to track them anymore.
    EntityPlayerMP.onUpdate()
    handleDestroyEntity()

    WorldClient.removeEntityFromWorld
    Packet30Entity,
    Packet31RelEntityMove,
    Packet32EntityLook,
    Packet33RelEntityMoveLook
    Tell the client the relative movement and/or yaw+pitch of the entity.

    EntityTrackerEntry
    .sendLocationToAllClients()

    .handleEntity()
    Update position (based on relative movement) and/or yaw/pitch.
    Entity.setPositionAndRotation2()
    Packet34EntityTeleport
    Move the Entity to the specified position, yaw+pitch
    EntityTrackerEntry
    .sendLocationToAllClients()
    Performs teleport instead of relative movement: once every 20 seconds, if riding, or if movement is too big.
    .handleEntityTeleport()
    Set entity position to the specified position, yaw+pitch
    Entity.setPositionAndRotation2()
    Packet35EntityHeadRotation
    EntityTrackerEntry
    .sendLocationToAllClients()
    .handleEntityHeadRotation()
    Sets the entity�s head to the given yaw
    Entity. setRotationYawHead
    Packet38EntityStatus
    2 = hurt, 3 = dead
    EntityPlayerMP.onItemUseFinish()
    WorldServer.setEntityState()
    .handleEntityStatus()
    calls Entity.handleHealthUpdate(), which plays appropriate sound and calls appropriate client method
    Entity
    .attackEntityFrom()
    .onDeath()
    Packet39AttachEntity
    Sends mounting / leashing info for horse, boat, etc.
    EntityPlayerMP.mountEntity
    EntityTrackerEntry
    EntityLiving
    .handleAttachEntity()
    mounts / leashes or unmounts / unleashes entity � horse, boat, cart, etc
    EntityLiving
    EntityBoat
    Packet40EntityMetadata
    Copy all changed metadata (WatchedObjects) to client (and optionally, clear the �changed� flag .watched for each)
    EntityTrackerEntry
    .handleEntityMetadata()
    Transmit all metadata for the entity that has been changed (�.watched� flag is true).  The �.watched� flag for each is optionally cleared when the packet is created.
    Entity.DataWatcher
    .updateWatchedObjectsFromList
    Packet41EntityEffect
    Apply the potion effect to the entity
    EntityTrackerEntry
    EntityPlayerMP
    ServerConfigurationManager
    .handleEntityEffect()
    Apply the potion effect to the entity
    EntityLivingBase.addPotionEffect()
    Packet42RemoveEntityEffect
    Remove a potion effect from the entity
    EntityPlayerMP
    .handleRemoveEntityEffect()
    EntityLivingBase. removePotionEffectClient
    Packet43Experience
    Set player experience
    EntityPlayerMP
    ServerConfigurationManager
    .handleExperience()
    sets the client player experience & level
    EntityClientPlayerMP.setXPstats
    Packet44UpdateAttributes
    Send all Attributes for this entity to the client.
    EntityTrackerEntry
    .handleUpdateAttributes()
    set the attributes of the client entity
    EntityLivingBase.getAttributeMap() (the elements in the map are overwritten).
    Packet200Statistic
    Send statistics (achievement, distance walked, or similar)
    EntityPlayerMP
    .handleStatistic()
    EntityClientPlayerMP
    .incrementStat
    Packet201PlayerInfo
    Send network info about a player to client (name, connected?, ping)
    ServerConfigurationManager
    .handlePlayerInfo()
    NetClientHandler
    Packet202PlayerAbilities
    Inform the client of the player�s abilities (can fly, walk speed, etc)
    EntityPlayerMP
    ServerConfigurationManager
    .handlePlayerAbilities()
    NB - .allowEdit is ignored

    EntityClientPlayerMP

    There are also two FMLpackets used for custom entities:

    Typical Server origin
    FMLClientHandler (Client processing)
    Called by Client during processing
    EntitySpawnPacket
    FMLNetworkHandler
    .getEntitySpawningPacket
    (from EntityTrackerEntry)
    EntitySpawnPacket.execute()
    FMLClientHandler
    .spawnEntityIntoClientWorld()
    EntitySpawnAdjustmentPacket
    FMLNetworkHandler
    .makeEntitySpawnAdjustment
    (from EntityTrackerEntry)
    EntitySpawnAdjustmentPacket.execute()
    FMLClientHandler
    .adjustEntityLocationOnClient()

    Server Packets: Miscellaneous


    Miscellaneous packets that I didn�t know where else to put.



    Typical server origin
    NetClientHandler (Client processing)
    Called by Client during processing
    Packet3Chat
    Chat messages including commands
    EntityPlayerMP
    .handleChat()
    Print to GUI
    FMLNetworkHandler.handleChatMessage()
    Forge Event: ClientChatReceivedEvent
    GUINewChat.printChatMessage()
    Packet4UpdateTime
    Synchronise Client time from server
    MinecraftServer
    ServerConfigurationManager
    .handleUpdateTime()
    Synchronise world�s time to server

    Packet203AutoComplete
    Server sends possible autocompletions for the given string fragment previously sent by the client
    NetServerHandler
    .handleAutoComplete()

    .handleAutoComplete()
    inserts the possible autocompletions into the GUIchat
    GUIchat
    Packet206SetObjective
    to
    Packet209SetPlayerTeam
    ServerScoreboard
    Handle teams and objectives, not sure what these are for.

    Packet250CustomPayload
    Channel (string)
    Length
    Rawdata (byte stream)
    Vanilla:
    ServerConfigurationManager
    EntityPlayerMP
    NetClientHandler

    ForgePacket
    FML.common.network

    .handleCustomPayload()
    Channels starting with MC| are handled by vanilla code (Request texture pack load; login information; merchant transaction information)
    Channels starting with FML are sent to handleFMLPacket.
    All others are sent to NetworkRegistry.handleCustomPacket (mod can register a custom handler)
    FMLNetworkHandler.handlePacket250Packet
    handleFMLPacket;
    handleVanilla250Packet
    Packets 252+ : connection maintenance




    There are also a number of packets used by Forge - see FMLPacket.
    The most relevant ones are
    • EntitySpawnPacket - which gets passed to a user-supplied function when the entity spawns.
    • EntitySpawnAdjustmentPacket - used to adjust an Entity's location
    • OpenGuiPacket - opens a Graphical User Interface screen on the client or server.





     

    My Blog Copyright © 2012 Fast Loading -- Powered by Blogger