001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package net.tridentsdk.server.packets.play.in; 019 020import io.netty.buffer.ByteBuf; 021import net.tridentsdk.event.player.PlayerToggleFlyingEvent; 022import net.tridentsdk.registry.Registered; 023import net.tridentsdk.server.netty.ClientConnection; 024import net.tridentsdk.server.netty.packet.InPacket; 025import net.tridentsdk.server.netty.packet.Packet; 026import net.tridentsdk.server.player.PlayerConnection; 027import net.tridentsdk.server.player.TridentPlayer; 028import net.tridentsdk.world.settings.GameMode; 029 030/** 031 * Packet is sent when the player starts/stops flying with the second parameter changed accordingly. All other 032 * parameters are ignored by the vanilla server. 033 */ 034public class PacketPlayInPlayerAbilities extends InPacket { 035 036 /** 037 * The flags are whether damage is disabled (god mode, 8, bit 3), whether the player can fly (4, bit 2), whether 038 * the 039 * player is flying (2, bit 1), and whether the player is in creative mode (1, bit 0). To get the values of 040 * these booleans, simply AND (&) the byte with 1,2,4 and 8 respectively, to get the 0 or 1 bitwise value. To set 041 * them OR (|) them with their repspective masks. 042 */ 043 protected byte flags; 044 045 /** 046 * Previous integer value divided by 250 047 */ 048 protected float flyingSpeed; 049 /** 050 * Previous integer value divided by 250 051 */ 052 protected float walkingSpeed; 053 054 @Override 055 public int id() { 056 return 0x12; 057 } 058 059 @Override 060 public Packet decode(ByteBuf buf) { 061 this.flags = buf.readByte(); 062 063 this.flyingSpeed = buf.readFloat(); 064 this.walkingSpeed = buf.readFloat(); 065 066 return this; 067 } 068 069 public byte flags() { 070 return this.flags; 071 } 072 073 public float flyingSpeed() { 074 return this.flyingSpeed; 075 } 076 077 public float walkingSpeed() { 078 return this.walkingSpeed; 079 } 080 081 @Override 082 public void handleReceived(ClientConnection connection) { 083 TridentPlayer player = ((PlayerConnection) connection).player(); 084 085 boolean flying = (byte) (flags & 2) == 2; 086 087 if(player.gameMode() == GameMode.CREATIVE || flying != player.isFlying()) { 088 PlayerToggleFlyingEvent toggleFly = new PlayerToggleFlyingEvent(player, flying, player.isFlyMode()); 089 090 // if the player doesn't have fly mode and is attempting to fly, make the event default to cancelled 091 if (!player.isFlyMode() && flying) { 092 toggleFly.cancel(true); 093 } 094 095 // If the player is flying and sends a flying=false flag, stop flying 096 if (player.isFlying() && !flying) { 097 toggleFly.cancel(true); 098 } 099 100 Registered.events().fire(toggleFly); 101 102 player.setFlying(!toggleFly.isIgnored()); 103 } 104 105 // TODO: act accordingly 106 } 107}