2020-01-09 03:05:42 +00:00
/ *
* Copyright ( c ) 2019 - 2020 GeyserMC . http : //geysermc.org
*
* 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 .
*
* @author GeyserMC
* @link https : //github.com/GeyserMC/Geyser
* /
2019-10-09 18:39:38 +00:00
package org.geysermc.connector.network.translators.java.entity.player ;
2019-09-16 22:28:29 +00:00
2020-05-23 21:06:34 +00:00
import org.geysermc.connector.GeyserConnector ;
2020-11-20 19:56:39 +00:00
import org.geysermc.connector.entity.player.PlayerEntity ;
2020-03-24 04:24:17 +00:00
import org.geysermc.connector.network.session.GeyserSession ;
import org.geysermc.connector.network.translators.PacketTranslator ;
import org.geysermc.connector.network.translators.Translator ;
2020-12-04 21:55:24 +00:00
import org.geysermc.connector.skin.SkinManager ;
2020-03-24 04:24:17 +00:00
2019-09-16 22:28:29 +00:00
import com.github.steveice10.mc.protocol.data.game.PlayerListEntry ;
import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction ;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPlayerListEntryPacket ;
2019-10-09 18:39:38 +00:00
import com.nukkitx.math.vector.Vector3f ;
2019-09-16 22:28:29 +00:00
import com.nukkitx.protocol.bedrock.packet.PlayerListPacket ;
2020-03-24 04:24:17 +00:00
@Translator ( packet = ServerPlayerListEntryPacket . class )
2019-09-16 22:28:29 +00:00
public class JavaPlayerListEntryTranslator extends PacketTranslator < ServerPlayerListEntryPacket > {
@Override
public void translate ( ServerPlayerListEntryPacket packet , GeyserSession session ) {
2020-05-26 03:39:57 +00:00
if ( packet . getAction ( ) ! = PlayerListEntryAction . ADD_PLAYER & & packet . getAction ( ) ! = PlayerListEntryAction . REMOVE_PLAYER )
return ;
2019-09-16 22:28:29 +00:00
PlayerListPacket translate = new PlayerListPacket ( ) ;
2020-02-06 00:55:34 +00:00
translate . setAction ( packet . getAction ( ) = = PlayerListEntryAction . ADD_PLAYER ? PlayerListPacket . Action . ADD : PlayerListPacket . Action . REMOVE ) ;
2019-09-16 22:28:29 +00:00
for ( PlayerListEntry entry : packet . getEntries ( ) ) {
2020-05-26 03:39:57 +00:00
switch ( packet . getAction ( ) ) {
case ADD_PLAYER :
PlayerEntity playerEntity ;
boolean self = entry . getProfile ( ) . getId ( ) . equals ( session . getPlayerEntity ( ) . getUuid ( ) ) ;
if ( self ) {
// Entity is ourself
playerEntity = session . getPlayerEntity ( ) ;
2020-12-04 21:55:24 +00:00
//TODO: playerEntity.setProfile(entry.getProfile()); seems to help with online mode skins but needs more testing to ensure Floodgate skins aren't overwritten
SkinManager . requestAndHandleSkinAndCape ( playerEntity , session , skinAndCape - >
2020-10-15 03:34:24 +00:00
GeyserConnector . getInstance ( ) . getLogger ( ) . debug ( " Loaded Local Bedrock Java Skin Data " ) ) ;
2020-05-26 03:39:57 +00:00
} else {
playerEntity = session . getEntityCache ( ) . getPlayerEntity ( entry . getProfile ( ) . getId ( ) ) ;
}
if ( playerEntity = = null ) {
// It's a new player
playerEntity = new PlayerEntity (
entry . getProfile ( ) ,
- 1 ,
session . getEntityCache ( ) . getNextEntityId ( ) . incrementAndGet ( ) ,
Vector3f . ZERO ,
Vector3f . ZERO ,
Vector3f . ZERO
) ;
}
session . getEntityCache ( ) . addPlayerEntity ( playerEntity ) ;
2019-09-16 22:28:29 +00:00
2020-05-23 21:06:34 +00:00
playerEntity . setProfile ( entry . getProfile ( ) ) ;
2020-05-26 03:39:57 +00:00
playerEntity . setPlayerList ( true ) ;
playerEntity . setValid ( true ) ;
2019-09-25 21:52:28 +00:00
2020-12-04 21:55:24 +00:00
PlayerListPacket . Entry playerListEntry = SkinManager . buildCachedEntry ( session , playerEntity ) ;
2019-10-10 21:16:07 +00:00
2020-05-26 03:39:57 +00:00
translate . getEntries ( ) . add ( playerListEntry ) ;
break ;
case REMOVE_PLAYER :
PlayerEntity entity = session . getEntityCache ( ) . getPlayerEntity ( entry . getProfile ( ) . getId ( ) ) ;
2020-09-16 04:18:18 +00:00
if ( entity ! = null ) {
// Just remove the entity's player list status
// Don't despawn the entity - the Java server will also take care of that.
2020-05-26 03:39:57 +00:00
entity . setPlayerList ( false ) ;
}
2020-09-16 04:18:18 +00:00
// As the player entity is no longer present, we can remove the entry
session . getEntityCache ( ) . removePlayerEntity ( entry . getProfile ( ) . getId ( ) ) ;
2020-08-07 16:33:21 +00:00
if ( entity = = session . getPlayerEntity ( ) ) {
// If removing ourself we use our AuthData UUID
translate . getEntries ( ) . add ( new PlayerListPacket . Entry ( session . getAuthData ( ) . getUUID ( ) ) ) ;
} else {
translate . getEntries ( ) . add ( new PlayerListPacket . Entry ( entry . getProfile ( ) . getId ( ) ) ) ;
}
2020-05-26 03:39:57 +00:00
break ;
2019-09-16 22:28:29 +00:00
}
}
2019-10-09 18:39:38 +00:00
2019-10-10 21:16:07 +00:00
if ( packet . getAction ( ) = = PlayerListEntryAction . REMOVE_PLAYER | | session . getUpstream ( ) . isInitialized ( ) ) {
2020-05-05 15:51:43 +00:00
session . sendUpstreamPacket ( translate ) ;
2019-10-09 18:39:38 +00:00
}
2019-09-16 22:28:29 +00:00
}
}