func (cc *GameConnection) HandleEncryptedConnection() { defer func() { cc.EntityServer.SendMessage(&protobuf.PlayerAction{ Player: cc.Player, Action: protobuf.PlayerAction_LEAVE, }) }() go func() { for cc.EntityServer != nil { time.Sleep(1 * time.Second) cc.Server.PlayerConnections[cc.Player.Uuid] <- protocol.CreatePacket(protocol.KeepAliveID, int32(time.Now().Nanosecond())) } }() for cc.EntityServer != nil { cc.Conn.SetReadDeadline(time.Now().Add(time.Second * 30)) id, buf, err := protocol.ReadPacket(cc.ConnEncrypted) n := 0 if err != nil { if err != io.EOF { log.Printf("Error reading packet: %s", err.Error()) } return } else if id == 0x01 { message, _ := protocol.ReadString(buf, 0) if len(message) > 0 && message[0] != '/' { cc.EntityServer.SendMessage(&protobuf.ChatMessage{ Message: message, Uuid: cc.Player.Uuid, }) } } else if id == 0x04 { cc.Player.X, n = protocol.ReadDouble(buf, n) cc.Player.FeetY, n = protocol.ReadDouble(buf, n) cc.Player.HeadY, n = protocol.ReadDouble(buf, n) cc.Player.Z, n = protocol.ReadDouble(buf, n) cc.Player.OnGround, n = protocol.ReadBool(buf, n) cc.EntityServer.SendMessage(&protobuf.PlayerAction{ Player: cc.Player, Action: protobuf.PlayerAction_MOVE_ABSOLUTE, Flags: 1, }) } else if id == 0x05 { cc.Player.Yaw, n = protocol.ReadFloat(buf, n) cc.Player.Pitch, n = protocol.ReadFloat(buf, n) cc.Player.OnGround, n = protocol.ReadBool(buf, n) cc.EntityServer.SendMessage(&protobuf.PlayerAction{ Player: cc.Player, Action: protobuf.PlayerAction_MOVE_ABSOLUTE, Flags: 2, }) } else if id == 0x06 { cc.Player.X, n = protocol.ReadDouble(buf, n) cc.Player.FeetY, n = protocol.ReadDouble(buf, n) cc.Player.HeadY, n = protocol.ReadDouble(buf, n) cc.Player.Z, n = protocol.ReadDouble(buf, n) cc.Player.Yaw, n = protocol.ReadFloat(buf, n) cc.Player.Pitch, n = protocol.ReadFloat(buf, n) cc.Player.OnGround, n = protocol.ReadBool(buf, n) cc.EntityServer.SendMessage(&protobuf.PlayerAction{ Player: cc.Player, Action: protobuf.PlayerAction_MOVE_ABSOLUTE, Flags: 3, }) } else if id == 0x07 { status, n := protocol.ReadByte(buf, n) x, n := protocol.ReadInt(buf, n) y, n := protocol.ReadByte(buf, n) z, n := protocol.ReadInt(buf, n) face, n := protocol.ReadByte(buf, n) chunkConn, err := cc.Server.Cluster.ChunkConnection(int64(x), int64(z), cc.Server) if err != nil { log.Print("Tried to destroy block on missing chunk server: ", err) } chunkConn.SendMessage(&protobuf.BlockUpdate{ X: int64(x), Y: uint32(y), Z: int64(z), BlockId: 0, Uuid: cc.Player.Uuid, }) log.Printf("digging block %d, %d, %d - status %d - face %d", x, y, z, status, face) } else if id == 0x08 { x, n := protocol.ReadInt(buf, n) y, n := protocol.ReadByte(buf, n) z, n := protocol.ReadInt(buf, n) face, n := protocol.ReadByte(buf, n) blockId, n := protocol.ReadShort(buf, n) quantity, n := protocol.ReadByte(buf, n) damage, n := protocol.ReadShort(buf, n) nbtLen, n := protocol.ReadShort(buf, n) if nbtLen > 0 { n += nbtLen } cursorX, n := protocol.ReadByte(buf, n) cursorY, n := protocol.ReadByte(buf, n) cursorZ, n := protocol.ReadByte(buf, n) if blockId > 0 && blockId < 256 && face < 6 { chunkConn, err := cc.Server.Cluster.ChunkConnection(int64(x), int64(z), cc.Server) if err != nil { log.Print("Tried to destroy block on missing chunk server: ", err) } switch face { case 0: y-- case 1: y++ case 2: z-- case 3: z++ case 4: x-- case 5: x++ } chunkConn.SendMessage(&protobuf.BlockUpdate{ X: int64(x), Y: uint32(y), Z: int64(z), BlockId: int32(blockId), BlockMetadata: int32(damage), Uuid: cc.Player.Uuid, }) } log.Printf("right clicked %d, %d, %d - face %d, blockId %d, quantity %d, damage %d, curX %d, curY %d, curZ %d", x, y, z, face, blockId, quantity, damage, cursorX, cursorY, cursorZ) } } }
func (s *Server) HandleMessage(message interface{}, conn *network.InternalConnection) { switch msg := message.(type) { case *protobuf.ChunkResponse: s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.MapChunkBulkID, int16(1), int32(len(msg.Data)), true, msg.Data, int32(msg.X), int32(msg.Z), uint16(0xFFFF), uint16(0)) case *protobuf.ChatMessage: s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.ChatMessageID, msg.Message) case *protobuf.BlockUpdate: log.Printf("Sending block update to: %s", msg.Uuid) s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.BlockChangeID, int32(msg.X), uint8(msg.Y), int32(msg.Z), protocol.Varint{uint64(msg.BlockId)}, uint8(msg.BlockMetadata)) case *protobuf.PlayerAction: switch msg.Action { case protobuf.PlayerAction_JOIN: s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.PlayerListItemID, msg.Player.Username, true, int16(0)) s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.ChatMessageID, protocol.CreateJsonMessage(msg.Player.Username+" joined the game", "yellow")) if msg.Uuid != msg.Player.Uuid { meta := protocol.NewMetadata( protocol.AbsorptionHeartsID, float32(0), protocol.OnFireID, false, protocol.UnknownBitFieldID, byte(0), protocol.AirID, uint16(0x012c), protocol.ScoreID, uint32(0), protocol.HealthID, float32(20), protocol.PotionColorID, int32(0), protocol.AmbientPotionID, byte(0), protocol.ArrowCountID, byte(0), ) s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.SpawnPlayerID, protocol.Varint{uint64(msg.Player.EntityId)}, msg.Player.Uuid, msg.Player.Username, protocol.Varint{0}, int32(msg.Player.X*32), int32(msg.Player.FeetY*32), int32(msg.Player.Z*32), byte(msg.Player.Yaw*256/2/math.Pi), byte(msg.Player.Pitch*256/2/math.Pi), int16(0), meta, ) s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.EntityMetadataID, int32(msg.Player.EntityId), meta, ) s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.EntityPropertiesID, int32(msg.Player.EntityId), int32(2), "generic.maxHealth", float64(20), int16(0), "generic.movementSpeed", float64(0.1), int16(0), ) s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.EntityTeleportID, int32(msg.Player.EntityId), int32(msg.Player.X*32), int32(msg.Player.FeetY*32), int32(msg.Player.Z*32), byte(msg.Player.Yaw*256/360), byte(msg.Player.Pitch*256/360), ) } case protobuf.PlayerAction_MOVE_RELATIVE: if msg.Flags == 1 { s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.EntityRelativeMoveID, int32(msg.Player.EntityId), byte(msg.Player.X*32), byte(msg.Player.FeetY*32), byte(msg.Player.Z*32), ) } else if msg.Flags == 2 { s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.EntityLookID, int32(msg.Player.EntityId), byte(msg.Player.Yaw*256/360), byte(msg.Player.Pitch*256/360), ) } else if msg.Flags == 3 { s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.EntityLookAndMoveID, int32(msg.Player.EntityId), byte(msg.Player.X*32), byte(msg.Player.FeetY*32), byte(msg.Player.Z*32), byte(msg.Player.Yaw*256/360), byte(msg.Player.Pitch*256/360), ) } if msg.Flags&2 == 2 { s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.EntityHeadLookID, int32(msg.Player.EntityId), byte(msg.Player.Yaw*256/360)) } case protobuf.PlayerAction_MOVE_ABSOLUTE: s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.EntityTeleportID, int32(msg.Player.EntityId), int32(msg.Player.X*32), int32(msg.Player.FeetY*32), int32(msg.Player.Z*32), byte(msg.Player.Yaw*256/360), byte(msg.Player.Pitch*256/360), ) s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.EntityHeadLookID, int32(msg.Player.EntityId), byte(msg.Player.Yaw*256/360)) case protobuf.PlayerAction_LEAVE: s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.DestroyEntitiesID, byte(1), int32(msg.Player.EntityId)) s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.PlayerListItemID, msg.Player.Username, false, int16(0)) s.PlayerConnections[msg.Uuid] <- protocol.CreatePacket(protocol.ChatMessageID, protocol.CreateJsonMessage(msg.Player.Username+" left the game", "yellow")) } } }